﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics.Contracts;
using System.Globalization;

namespace YasharEl.Infrastructure
{
    public static class TypeExtensions
    {
        /// <summary>
        /// Correctly formats the FullName of the specified type by taking generics into consideration.
        /// </summary>
        /// <param name="type">The type whose full name is formatted.</param>
        /// <returns>A correctly formatted full name.</returns>
        public static string FullNameToString(this Type type)
        {
            Contract.Requires<ArgumentNullException>(type != null, "type could not be null.");

            if (!type.IsGenericType)
            {
                return type.FullName;
            }

            string value = type.FullName.Substring(0, type.FullName.IndexOf('`')) + "<";
            Type[] genericArgs = type.GetGenericArguments();
            var list = new List<string>();

            for (int i = 0; i < genericArgs.Length; i++)
            {
                value += "{" + i + "},";
                string s = FullNameToString(genericArgs[i]);
                list.Add(s);
            }

            value = value.TrimEnd(',');
            value += ">";
            value = string.Format(CultureInfo.InvariantCulture, value, list.ToArray());
            return value;
        }

        /// <summary>
        /// Returns true if the type can be serialized as is.
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static bool IsSimpleType(this Type type)
        {
            return (type == typeof(string) ||
                    type.IsPrimitive ||
                    type == typeof(decimal) ||
                    type == typeof(Guid) ||
                    type == typeof(DateTime) ||
                    type == typeof(TimeSpan) ||
                    type == typeof(DateTimeOffset) ||
                    type.IsEnum);
        }
    }
}
